// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package androidx.gdata.blogger;

import androidx.gdata.GDataServer;
import androidx.gdata.LinkUrlUtil;
import androidx.gdata.LinkUrl;
import androidx.gdata.blogger.xml.BlogCollectionDeserializer;
import androidx.gdata.blogger.xml.BlogSerializer;
import androidx.gdata.blogger.xml.BlogDeserializer;
import androidx.gdata.blogger.xml.BlogEntryCollectionDeserializer;
import androidx.gdata.blogger.xml.BlogEntrySerializer;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.net.MalformedURLException;

import org.w3c.dom.Node;

final class BloggerServerImpl extends GDataServer implements BloggerServer {
  private static BlogCollectionDeserializer blogCollectionDeserializer = new BlogCollectionDeserializer();
  private static BlogEntrySerializer entrySerializer = new BlogEntrySerializer(true);
  private static BlogSerializer blogSerializer = new BlogSerializer(true);
  private static BlogDeserializer blogDeserializer = new BlogDeserializer();
  private static BlogEntryCollectionDeserializer entryCollectionBuilder = new BlogEntryCollectionDeserializer();

  private URL url;

  BloggerServerImpl(String baseUrl, String username, String auth) {
    super(baseUrl, username, auth);
    try {
      url = new URL(baseUrl);
    } catch (MalformedURLException e) {
      throw new RuntimeException("Bad URL!", e);
    }
  }

  public BlogCollection getBlogCollection() throws IOException {
    String result = doAuthorizedGet(url);
    Node feedNode = extractFeedNode(result);
    return blogCollectionDeserializer.build(feedNode);
  }

  public Blog postBlogEntry(Blog blog, BlogEntry entry) throws IOException {
    LinkUrl postLink = LinkUrlUtil.getPostLink(blog);
    if (postLink == null) {
      throw new IOException("Bad BloggerFeed - no post link!");
    }
    StringWriter sw = new StringWriter();
    PrintWriter out = new PrintWriter(sw);
    entrySerializer.serialize(out, entry);
    out.flush();
    URL url = new URL(postLink.getHref());
    String atomPost = sw.toString();

    String rv = doAtomPost(url, atomPost);
//    System.out.println("rv:");
//    System.out.println(rv);
    Node entryNode = extractEntryNode(rv);
    if (entryNode == null) {
      throw new IOException("Cannot parse response: " + rv);
    }
    return blogDeserializer.build(entryNode);
  }

  public Blog editBlogEntry(BlogEntry entry) throws IOException {
    LinkUrl editLink = LinkUrlUtil.getEditLink(entry);
    if (editLink == null) {
      throw new IOException("Bad BloggerFeed - no edit link!");
    }
    StringWriter sw = new StringWriter();
    PrintWriter out = new PrintWriter(sw);
    out.println("<?xml version='1.0' encoding='utf-8'?>");
    entrySerializer.serialize(out, entry);
    out.flush();
    URL url = new URL(editLink.getHref());
    String atomPost = sw.toString();
//    System.out.println("atomPost:");
//    System.out.println(atomPost);

    String rv = doAtomPut(url, atomPost);
//    System.out.println("rv:");
//    System.out.println(rv);
    Node entryNode = extractEntryNode(rv);
    if (entryNode == null) {
      throw new IOException("Cannot parse response: " + rv);
    }
    return blogDeserializer.build(entryNode);
  }

  public void deleteBlogEntry(BlogEntry entry) throws IOException {
    LinkUrl editLink = LinkUrlUtil.getEditLink(entry);
    if (editLink == null) {
      throw new IOException("Bad BloggerFeed - no edit link!");
    }
    StringWriter sw = new StringWriter();
    PrintWriter out = new PrintWriter(sw);
    out.println("<?xml version='1.0' encoding='utf-8'?>");
    entrySerializer.serialize(out, entry);
    out.flush();
    URL url = new URL(editLink.getHref());
    String atomPost = sw.toString();
//    System.out.println("atomPost:");
//    System.out.println(atomPost);

    doAtomDelete(url, atomPost);
  }


  public BlogEntryCollection getBlogEntries(Blog blog) throws IOException {
    LinkUrl feedLink = LinkUrlUtil.getFeedLink(blog);
    if (feedLink == null) {
      throw new IOException("Bad Blog - no feed link!");
    }
    URL url = new URL(feedLink.getHref());
    String result = doAuthorizedGet(url);
    Node feedNode = extractFeedNode(result);
    return entryCollectionBuilder.build(feedNode);
  }

}
